package cn.xd.base.application.service.query.impl;

import cn.hutool.core.util.ObjUtil;
import cn.xd.base.application.assembler.AdminOrgAssembler;
import cn.xd.base.application.assembler.JsonAdminOrgTreeAssembler;
import cn.xd.base.application.dto.query.AdminOrgQuery;
import cn.xd.base.application.service.query.AdminOrgQueryAppService;
import cn.xd.base.domain.bean.response.AdminOrgDTO;
import cn.xd.base.domain.bean.response.JsonAdminOrgTree;
import cn.xd.base.persistence.dos.AdminOrgDO;
import cn.xd.base.persistence.mps.AdminOrgMpService;
import cn.xd.common.enums.common.CommonStatusEnum;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AdminOrgQueryAppServiceImpl implements AdminOrgQueryAppService {

    @Resource
    private AdminOrgMpService adminOrgMpService;

    @Override
    public List<AdminOrgDTO> getAdminOrgList(AdminOrgQuery adminOrgQuery) {
        AdminOrgDO adminOrgDO = adminOrgMpService.getResult(adminOrgQuery.getParentId()).get();
        if (ObjUtil.isNull(adminOrgDO) || adminOrgDO.getStatus().equals(CommonStatusEnum.DELETED.getCode())) {
            return new ArrayList<>();
        }
        return (List<AdminOrgDTO>)adminOrgMpService.getList(Wrappers.lambdaQuery(AdminOrgDO.class).eq(ObjUtil.isNotNull(adminOrgQuery.getParentId()), AdminOrgDO::getParentId, adminOrgQuery.getParentId())
                .ne(AdminOrgDO::getStatus, CommonStatusEnum.DELETED.getCode()), AdminOrgAssembler.INSTANCE).get();
    }

    @Override
    public Boolean checkHasName(String name, Long parentId, Long id) {
        return ObjUtil.isNotEmpty(adminOrgMpService.getAdminOrg(name, parentId, id).get());
    }

    @Override
    public List<Long> getAdminOrgChildrenIds(Long orgId) {
        List<Long> res = new ArrayList<>();
        AdminOrgDO adminOrgDO = adminOrgMpService.getResult(orgId).get();
        if (ObjUtil.isNull(adminOrgDO) || adminOrgDO.getStatus().equals(CommonStatusEnum.DELETED.getCode())) {
            return res;
        }
        Set<Long> orgIdSet = adminOrgMpService.lambdaQuery().likeRight(AdminOrgDO::getPath, adminOrgDO.getPath()).eq(AdminOrgDO::getStatus, CommonStatusEnum.ENABLE.getCode()).list()
                .stream().map(AdminOrgDO::getId).collect(Collectors.toSet());
        res.addAll(orgIdSet);
        return res;
    }

    private AdminOrgDTO getAdminOrg(Long id) {
        AdminOrgDO adminOrgDO = adminOrgMpService.getById(id);
        return AdminOrgAssembler.INSTANCE.fromData(adminOrgDO);
    }

    @Override
    public JsonAdminOrgTree getAdminOrgJsonTree(Long id) {
        AdminOrgDTO adminOrgDTO = getAdminOrg(id);
        JsonAdminOrgTree jsonAdminOrgTree = JsonAdminOrgTreeAssembler.INSTANCE.toTree(adminOrgDTO);
        List<JsonAdminOrgTree> jsonAdminOrgTrees = this.getAdminOrgJsonTreeByParentId(adminOrgDTO.getId());
        if (CollectionUtils.isEmpty(jsonAdminOrgTrees)) {
            jsonAdminOrgTree.setChildren(null);
        } else {
            jsonAdminOrgTree.setChildren(jsonAdminOrgTrees);
        }
        return jsonAdminOrgTree;
    }

    @Override
    public List<JsonAdminOrgTree> getAdminOrgJsonTreeByParentId(Long parentId) {
        List<JsonAdminOrgTree> trees = new ArrayList<>();
        AdminOrgQuery adminOrgQuery = new AdminOrgQuery();
        adminOrgQuery.setParentId(parentId);
        List<AdminOrgDTO> adminOrgList = this.getAdminOrgList(adminOrgQuery);
        for (AdminOrgDTO adminOrgDTO : adminOrgList) {
            JsonAdminOrgTree jsonAdminOrgTree = JsonAdminOrgTreeAssembler.INSTANCE.toTree(adminOrgDTO);
            List<JsonAdminOrgTree> jsonAdminOrgTrees = this.getAdminOrgJsonTreeByParentId(adminOrgDTO.getId());
            if (CollectionUtils.isEmpty(jsonAdminOrgTrees)) {
                jsonAdminOrgTree.setChildren(null);
            } else {
                jsonAdminOrgTree.setChildren(jsonAdminOrgTrees);
            }
            trees.add(jsonAdminOrgTree);
        }
        return trees;
    }
}
